package com.campus.service.impl;

import com.alibaba.fastjson2.JSON;
import com.campus.common.CampusWall;
import com.campus.common.RedisCache;
import com.campus.common.Result;
import com.campus.entity.PostDetailDTO;
import com.campus.entity.PostLikes;
import com.campus.entity.Posts;
import com.campus.entity.Users;
import com.campus.mapper.CategoriesMapper;
import com.campus.mapper.PostLikesMapper;
import com.campus.mapper.PostsMapper;
import com.campus.mapper.PostViewsMapper;
import com.campus.service.PostService;
import com.campus.utils.AllUtils;
import com.campus.utils.SnowFlakeUtil;
import com.campus.utils.TokenUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.ArrayList;

import com.alibaba.fastjson2.JSONArray;

@Service
public class PostServiceImpl implements PostService {
    @Autowired
    private TokenUtils tokenUtils;
    @Autowired
    private PostsMapper postsMapper;
    @Autowired
    private CategoriesMapper categoriesMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private PostLikesMapper postLikesMapper;
    @Autowired
    private PostViewsMapper postViewsMapper;


    /**
     * 创建帖子
     *
     * @param post
     * @param token
     * @return
     */
    @Override
    public Result createPost(Posts post, String token) {
        if (token != null && token.startsWith("Bearer ")) {
            token = token.substring(7); // 移除 "Bearer " 副本
        }
        Users currentUser = tokenUtils.getCurrentUser(token);
        post.setPostId(SnowFlakeUtil.getId().toString());
        post.setUserId(currentUser.getUserId());
        post.setJsonImages(JSON.toJSONString(post.getImages()));
        String categoryId = categoriesMapper.selectCategoriesBySortOrder(post.getCategoryId());
        post.setCategoryId(categoryId);
        Long categoryKeysDelete;
        Long UserKeysDelete;
        //延迟双删
        Set<String> categoryKeys = stringRedisTemplate.keys("category*");
        Set<String> UserKeys = stringRedisTemplate.keys("userId*");
        categoryKeysDelete = stringRedisTemplate.delete(categoryKeys);
        UserKeysDelete = stringRedisTemplate.delete(UserKeys);
        int i = postsMapper.insertPost(post);

        if (i > 0) {
            //这里上传帖子成功之后要将缓存中的删除掉
//            Set<String> categoryKeys = stringRedisTemplate.keys("category*");
//            Set<String> UserKeys = stringRedisTemplate.keys("userId*");

            categoryKeysDelete = stringRedisTemplate.delete(categoryKeys);
            UserKeysDelete = stringRedisTemplate.delete(UserKeys);
            // 修复：即使没有缓存需要删除，也应该认为是成功的
            if (categoryKeysDelete >= 0L || UserKeysDelete >= 0L) {
                //这个是统计今日的帖子发布情况
                countByDateAndCategory(post);
                return Result.ok("帖子上传成功");
            } else {
                return Result.err(Result.CODE_500, "服务器内部错误");
            }

        }
        return Result.err(Result.CODE_500, "帖子上传失败");
    }

    /**
     * 查询帖子
     *
     * @param page
     * @param size
     * @param category
     * @return
     */
    @Override
    public Result getPostsList(int page, int size, int category) {
        PageHelper.startPage(page, size);
        String postsRedisStr = getRedisStrByCategory(page, size, category);
        //来到这先查询缓存
        String postLists = stringRedisTemplate.opsForValue().get(postsRedisStr);
        PageInfo<Posts> postsPageInfo = null;
        if (StringUtils.hasText(postLists)) {
            postsPageInfo = JSON.parseObject(postLists, PageInfo.class);
            return Result.ok(postsPageInfo);
        }

        List<Posts> postsList = postsMapper.getPostsList(category);
        for (Posts p : postsList) {
            Integer allLikesByPostId = postLikesMapper.getAllLikesByPostId(p.getPostId());
            if (allLikesByPostId == null) {
                allLikesByPostId = 0;
            }
            p.setLikesCount(allLikesByPostId);
        }
        postsPageInfo = new PageInfo<Posts>(postsList);
        stringRedisTemplate.opsForValue().set(postsRedisStr, JSON.toJSONString(postsPageInfo), 24, TimeUnit.HOURS);
        PageHelper.clearPage();
        return Result.ok(postsPageInfo);
    }

    /**
     * 获取用户发布的所有的帖子
     *
     * @param userId
     * @param size
     * @param page
     * @param request
     * @return
     */
    @Override
    public Result getUserPosts(String userId, int size, int page, HttpServletRequest request) {
        PageHelper.startPage(page, size);
        //得到用户的信息
        String token = request.getHeader(CampusWall.CAMPUS_TOKEN);
        token = tokenUtils.getToken(token);
        //得到用户信息
        Users currentUser = tokenUtils.getCurrentUser(token);
        String redisStrByUser = getRedisStrByUser(page, size, userId);
        String userPosts = stringRedisTemplate.opsForValue().get(redisStrByUser);
        PageInfo<Posts> postsPageInfo = null;
        if (StringUtils.hasText(userPosts)) {
            postsPageInfo = JSON.parseObject(userPosts, PageInfo.class);
            return Result.ok(postsPageInfo);
        }
        List<Posts> postsList = postsMapper.getUserPosts(userId);
        postsPageInfo = new PageInfo<Posts>(postsList);
        stringRedisTemplate.opsForValue().set(redisStrByUser, JSON.toJSONString(postsPageInfo));
        PageHelper.clearPage();
        return Result.ok(postsPageInfo);
    }

    //根据postid查询post帖子
    @Override
    public Result getPostById(String postId) {
        Posts post = postsMapper.getPostById(postId);
        if (post != null) {
            return Result.ok(post);
        }
        return Result.err(Result.CODE_500, "服务器内部错误");
    }

    // 获取帖子详情（包含用户和分类信息）
    @Override
    public Result getPostDetailById(String postId) {
        PostDetailDTO postDetail = postsMapper.getPostDetailById(postId);
        if (postDetail != null) {
            // 处理图片路径，补全为完整URL
            // 从数据库中获取的images是JSON字符串格式，需要解析并处理
            if (postDetail.getImages() != null && !postDetail.getImages().isEmpty()) {
                try {
                    // 获取images字段的字符串表示
                    String imagesStr = postDetail.getImages();

                    // 检查是否是有效的JSON格式
                    if (imagesStr.startsWith("[") || imagesStr.startsWith("{")) {
                        // 是JSON格式，解析为JSONArray
                        JSONArray jsonArray = JSON.parseArray(imagesStr);
                        ArrayList<String> fullImageUrls = new ArrayList<>();
                        for (int i = 0; i < jsonArray.size(); i++) {
                            String imagePath = jsonArray.getString(i);
                            // 补全为完整URL
                            if (imagePath != null && !imagePath.isEmpty()) {
                                if (imagePath.startsWith("http")) {
                                    // 已经是完整URL
                                    fullImageUrls.add(imagePath);
                                } else if (imagePath.startsWith("/")) {
                                    // 以/开头的相对路径
                                    fullImageUrls.add("http://localhost:8081/api/file" + imagePath);
                                } else {
                                    // 其他相对路径
                                    fullImageUrls.add("http://localhost:8081/api/file/" + imagePath);
                                }
                            }
                        }
                        // 将处理后的图片列表转换为JSON字符串并设置回postDetail
                        postDetail.setImages(JSON.toJSONString(fullImageUrls));
                    }
                } catch (Exception e) {
                    // 解析失败，保持原样
                    System.out.println("图片解析失败: " + e.getMessage());
                }
            }

            // 获取帖子浏览量
            Integer viewCount = postViewsMapper.getViewCountByPostId(postId);
            if (viewCount != null) {
                postDetail.setViewsCount(viewCount);
            }

            // 获取帖子点赞数
            Integer likesCount = postLikesMapper.getAllLikesByPostId(postId);
            if (likesCount != null) {
                postDetail.setLikesCount(likesCount);
            }

            return Result.ok(postDetail);
        }
        return Result.err(Result.CODE_500, "未找到该帖子");
    }


    /**
     * 获取帖子焦点数据在redis中的名称
     *
     * @param page
     * @param size
     * @param category
     * @return
     */
    public String getRedisStrByCategory(int page, int size, int category) {
        return "categoryId:" + category + page + size;
    }

    /**
     * 获取用户据个人帖子焦点数据在redis中的名称
     *
     * @param page
     * @param size
     * @param userId
     * @return
     */
    public String getRedisStrByUser(int page, int size, String userId) {
        return "userId:" + userId + ":page:" + page + ":size:" + size;
    }

    /**
     * 删除帖子
     *
     * @param postId 帖子ID
     * @param userId 用户ID
     * @return 删除结果
     */
    @Override
    public Result deletePost(String postId, String userId) {
        // 先查询帖子是否存在
        Posts post = postsMapper.getPostById(postId);
        if (post == null) {
            return Result.err(Result.CODE_404, "帖子不存在");
        }

        // 检查是否是帖子的作者
        if (!post.getUserId().equals(userId)) {
            return Result.err(Result.CODE_403, "无权限删除该帖子");
        }

        // 删除帖子
        int result = postsMapper.deletePostById(postId);
        if (result > 0) {
            // 删除成功，清除相关缓存
            Set<String> categoryKeys = stringRedisTemplate.keys("category*");
            Set<String> userKeys = stringRedisTemplate.keys("userId*");
            stringRedisTemplate.delete(categoryKeys);
            stringRedisTemplate.delete(userKeys);

            // 更新热力榜数据 - 从Redis ZSet中移除该帖子
            String todayKey = RedisCache.HOT_RANKING_ZSET_KEY_PREFIX + "today";
            String weekKey = RedisCache.HOT_RANKING_ZSET_KEY_PREFIX + "week";
            String monthKey = RedisCache.HOT_RANKING_ZSET_KEY_PREFIX + "month";
            stringRedisTemplate.opsForZSet().remove(todayKey, postId);
            stringRedisTemplate.opsForZSet().remove(weekKey, postId);
            stringRedisTemplate.opsForZSet().remove(monthKey, postId);

            // 删除帖子详情缓存
            String postKey = RedisCache.HOT_RANKING_POST_KEY_PREFIX + postId;
            stringRedisTemplate.delete(postKey);

            return Result.ok("删除成功");
        } else {
            return Result.err(Result.CODE_500, "删除失败");
        }

    }

    public void countByDateAndCategory(Posts post) {
        //这个是统计今日的帖子发布情况
        String dayNumRedis = stringRedisTemplate.opsForValue().get(RedisCache.TODAY_POST_COUNT + post.getCategoryId());
        int dayNum = dayNumRedis == null ? 1 : Integer.valueOf(dayNumRedis) + 1;
        stringRedisTemplate.opsForValue().set(RedisCache.TODAY_POST_COUNT + post.getCategoryId(), dayNum + "");
        //这个是统计本周的帖子发布情况
        String weekNumRedis = stringRedisTemplate.opsForValue().get(RedisCache.WEEK_POST_COUNT + post.getCategoryId());
        int weenNum = weekNumRedis == null ? 1 : Integer.valueOf(weekNumRedis) + 1;
        stringRedisTemplate.opsForValue().set(RedisCache.WEEK_POST_COUNT + post.getCategoryId(), weenNum + "");
        //这个是统计本月的帖子发布情况
        String monthNumRedis = stringRedisTemplate.opsForValue().get(RedisCache.MONTH_POST_COUNT + post.getCategoryId());
        int monthNum = monthNumRedis == null ? 1 : Integer.valueOf(monthNumRedis) + 1;
        stringRedisTemplate.opsForValue().set(RedisCache.MONTH_POST_COUNT + post.getCategoryId(), monthNum + "");
        //设置过期时间
        stringRedisTemplate.expire(RedisCache.TODAY_POST_COUNT + post.getCategoryId(), AllUtils.getHoursToMidnightCeil(), TimeUnit.HOURS);
        stringRedisTemplate.expire(RedisCache.WEEK_POST_COUNT + post.getCategoryId(), AllUtils.getHoursToEndOfWeekCeil(), TimeUnit.HOURS);
        stringRedisTemplate.expire(RedisCache.MONTH_POST_COUNT + post.getCategoryId(), AllUtils.getHoursToEndOfMonthCeil(), TimeUnit.HOURS);

    }

    /**
     * 更新帖子内容
     */
    @Override
    public Result updatePost(String postId, Posts post, String userId) {
        // 查询原帖
        Posts existing = postsMapper.getPostById(postId);
        if (existing == null) {
            return Result.err(Result.CODE_404, "帖子不存在");
        }
        // 权限校验：仅作者可编辑
        if (!existing.getUserId().equals(userId)) {
            return Result.err(Result.CODE_403, "无权限编辑该帖子");
        }

        // 设置待更新字段
        Posts toUpdate = new Posts();
        toUpdate.setPostId(postId);
        toUpdate.setTitle(post.getTitle());
        toUpdate.setContent(post.getContent());
        // 分类：如果前端传了分类ID则更新
        if (post.getCategoryId() != null && post.getCategoryId().trim().length() > 0) {
            toUpdate.setCategoryId(post.getCategoryId());
        }
        // 图片：序列化为 JSON 字符串存入 images 列
        if (post.getImages() != null) {
            toUpdate.setJsonImages(JSON.toJSONString(post.getImages()));
        }

        int rows = postsMapper.updatePostById(toUpdate);
        if (rows > 0) {
            // 清理相关缓存
            Set<String> categoryKeys = stringRedisTemplate.keys("category*");
            Set<String> userKeys = stringRedisTemplate.keys("userId*");
            stringRedisTemplate.delete(categoryKeys);
            stringRedisTemplate.delete(userKeys);
            return Result.ok("更新成功");
        }
        return Result.err(Result.CODE_500, "更新失败");
    }
}
